在Javascript中,除了几种原始类型外,其余皆为对象(Object,Array ...),既然对象如此重要,那就列举一下在Javascript中如何创建对象:
通过Object构造函数创建对象实例
var person = new Object();
person.name = 'krew';
person.age = 26;
对象字面量
对象字面量是对象定义的一种简写形式,目的在于简化创建包含大量属性的对象的过程。
var person = {
name : 'krew',
age : 26
}
工厂模式
工厂模式是一种设计模式,通过对创建具体对象的过程进行抽象。使用函数来封装创建对象的细节,可以无数次地调用用该函数,每次都可以得到包含制定内容的对象。
function personFactory(name, age){
var obj = new Object();
obj.name = name;
obj.age = age;
obj.sayName = function(){
console.log(this.name);
}
return obj;
}
var person1 = personFactory('krew', 26);
var person2 = personFactory('john', 20);
构造函数模式
基于工厂模式创建对象虽然方便,但是创建出来的对象没有特定的对象类型(比如原生对象Object, Array的实例都有自己的类型),所以就采用构造函数模式来创建对象,就能解决识别对象类型的问题。
function Person(name, age){
this.name = name;
this.age = age;
this.sayName = function() {
console.log(this.name);
}
}
var person1 = new Person('krew', 26);
var person2 = new Person('john', 20);
person1.sayName(); // 'krew'
person2.sayName(); // 'john'
person1.constructor == Person // true
person2.constructor == Person // true
原型模式
每个函数在创建的时候,就会根据特定的规则为该函数创建一个prototype
属性,这个属性是指向函数的原型对象的指针。这个原型对象的包含可以由特定类型的所有实例共享的属性和方法。所以,在构造函数的prototype
属性上添加属性与方法,该构造函数的所有实例都会在原型链上查找到这些属性与方法。
function Person() {
}
Person.prototype.name = 'krew';
Person.prototype.age = 26;
Person.prototype.sayName = function() {
console.log(this.name);
}
var person1 = new Person();
var person2 = new Person();
person1.sayName(); // 'krew'
person2.sayName(); // 'krew'
组合构造函数和原型模式
由于原型对象中的属性是被很多实例所共享的,对于引用类型的属性值,将会存在实例间无法隔离的问题:
function Person() {
}
Person.prototype = {
constructor : Person,
name : 'krew',
age : 26,
friends : ['john', 'kitty'],
showFriends : function() {
console.log(this.friends);
}
}
var person1 = new Person();
var person2 = new Person();
person1.friends.push('petter');
person1.showFriends() // ['john', 'kitty', 'petter']
person2.showFriends() // ['john', 'kitty', 'petter']
可以看到,仅是在实例person1的friends属性上添加值,但person2也跟着变化。这是因为friends数组存在于Person.prototype而非person1中,person1与person2中的friends皆为引用Person.prototype中的friends,所以当通过person1来改变friends的时候,person2中的friends也会反映出来。
通过组合构造函数与原型模式可以解决上面出现的问题,构造函数模式用于定义实例属性,而原型模式用于定义方法和共享的属性,每个实例会有自己的一份实例属性,同时又共享着方法的引用,极大的节省了内存。
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayName = function() {
console.log(this.name);
}
var person1 = new Person('krew', 26);
var person2 = new Person('john', 20);
person1.sayName(); // 'krew'
person2.sayName(); // 'john'
动态原型模式
function Person(name, age){
this.name = name;
this.age = age;
if (typeof this.sayName != 'function') {
Person.prototype.sayName = function() {
console.log(this.name);
}
}
}
var person1 = new Person('krew', 26);
var person2 = new Person('john', 20);
person1.sayName(); // 'krew'
person2.sayName(); // 'john'
寄生构造函数模式
function Person(name, age) {
var obj = new Object();
obj.name = name;
obj.age = age;
obj.sayName = function() {
console.log(this.name);
}
return obj;
}
var person1 = new Person('krew', 26);
var person2 = new Person('john', 20);
person1.sayName(); // 'krew'
person2.sayName(); // 'john'
稳妥构造函数模式
function Person(name) {
var obj = new Object();
obj.sayName = function() {
console.log(name);
}
return obj;
}
var person1 = Person('krew');
var person2 = Person('john');
person1.sayName(); // 'krew'
person2.sayName(); // 'john'
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。